package com.wn.course.utils

import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.PopupWindow
import androidx.databinding.ObservableInt
import com.wn.common.model.SingleLiveData
import com.wn.course.databinding.*
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.scopes.ViewModelScoped
import javax.inject.Inject

/**
 * @Author: wn
 * @Date: 2023/8/10 17:05
 * @Description: popupWindow 初始化 和 点击事件处理
 * 注入 CourseFragment  函数调用传递所需参数
 */
@ViewModelScoped
class UseConfigPopFilter @Inject constructor(@ApplicationContext private val context: Context) {
  // popupWindow 在 activity 最上层显示一个弹窗
  private lateinit var popupWindowType: PopupWindow // 全部类型
  private lateinit var popupWindowLevel: PopupWindow // 全部难度
  private lateinit var popupWindowPrice: PopupWindow // 全部价格
  private lateinit var popupWindowSort: PopupWindow // 默认排序

  /**
   * 初始化配置 PopupWindow
   * @param mBinding FragmentCourseBinding
   * @param changePopValue Function4<[@kotlin.ParameterName] String?, [@kotlin.ParameterName] Int?, [@kotlin.ParameterName] Int?, [@kotlin.ParameterName] Int?, Unit>
   * @param refreshData Function0<Unit>
   */
  fun configPopFilter(
    mBinding: FragmentCourseBinding,
    changePopValue: (type: String?, level: Int?, price: Int?, sort: Int?) -> Unit,
    refreshData: () -> Unit,
  ) {
    // region 全部类型弹窗
    // dataBinding 实例化
    val popBindingType =
      PopCourseTypeBinding.inflate(LayoutInflater.from(context), null, false)

    // view 宽 高
    popupWindowType = PopupWindow(
      popBindingType.root,
      ViewGroup.LayoutParams.MATCH_PARENT,
      ViewGroup.LayoutParams.WRAP_CONTENT
    )
    // 控件获取到对应的值后改变 文字颜色 和 右边的勾显示与否
    val obType = ObservableInt(0)

    popBindingType.apply {
      // 传递 dataBinding
      ob = obType
      // 点击事件
      tvAllType.setOnClickListener {
        obType.set(0)
        mBinding.spinnerTypeCourseText.text = tvAllType.text
        changePopValue("all", null, null, null)
        refreshData()
        popupWindowType.dismiss()
      }
      tvBizType.setOnClickListener {
        obType.set(1)
        mBinding.spinnerTypeCourseText.text = tvBizType.text
        changePopValue("business", null, null, null)
        refreshData()
        popupWindowType.dismiss()
      }
      tvProType.setOnClickListener {
        obType.set(2)
        mBinding.spinnerTypeCourseText.text = tvProType.text
        changePopValue("specialty", null, null, null)
        refreshData()
        popupWindowType.dismiss()
      }
    }
    // endregion

    //region 全部难度弹窗
    val popBindingLevel = PopCourseLevelBinding.inflate(LayoutInflater.from(context), null, false)

    popupWindowLevel = PopupWindow(
      popBindingLevel.root,
      ViewGroup.LayoutParams.MATCH_PARENT,
      ViewGroup.LayoutParams.WRAP_CONTENT
    )

    //一个有初始值的observable，用来显示弹窗文字是否被点击和右边的勾显示与否，被点击set值，控件获取到对应的值后改变文字颜色
    val obLevel = ObservableInt(0)

    popBindingLevel.apply {
      obL = obLevel
      tvAll.setOnClickListener {
        obLevel.set(0)
        mBinding.spinnerLevelCourse.text = tvAll.text
        changePopValue(null, -1, null, null)
        refreshData()
        popupWindowLevel.dismiss()
      }
      tvTwo.setOnClickListener {
        obLevel.set(1)
        mBinding.spinnerLevelCourse.text = tvTwo.text
        changePopValue(null, 1, null, null)
        refreshData()
        popupWindowLevel.dismiss()
      }
      tvThree.setOnClickListener {
        obLevel.set(2)
        mBinding.spinnerLevelCourse.text = tvThree.text
        changePopValue(null, 2, null, null)
        refreshData()
        popupWindowLevel.dismiss()
      }
      tvFour.setOnClickListener {
        obLevel.set(3)
        mBinding.spinnerLevelCourse.text = tvFour.text
        changePopValue(null, 3, null, null)
        refreshData()
        popupWindowLevel.dismiss()
      }
      tvFive.setOnClickListener {
        obLevel.set(4)
        mBinding.spinnerLevelCourse.text = tvFive.text
        changePopValue(null, 4, null, null)
        refreshData()
        popupWindowLevel.dismiss()
      }
    }
    //endregion

    //region 全部价格弹窗
    val popBindingPrice =
      PopCoursePriceBinding.inflate(LayoutInflater.from(context), null, false)

    popupWindowPrice = PopupWindow(
      popBindingPrice.root,
      ViewGroup.LayoutParams.MATCH_PARENT,
      ViewGroup.LayoutParams.WRAP_CONTENT
    )

    //一个有初始值的observable，用来显示弹窗文字是否被点击和右边的勾显示与否，被点击set值，控件获取到对应的值后改变文字颜色
    val obPrice = ObservableInt(0)

    popBindingPrice.apply {
      obP = obPrice
      tvAll.setOnClickListener {
        obPrice.set(0)
        mBinding.spinnerPriceCourse.text = tvAll.text
        changePopValue(null, null, -1, null)
        refreshData()
        popupWindowPrice.dismiss()
      }
      tvTwo.setOnClickListener {
        obPrice.set(1)
        mBinding.spinnerPriceCourse.text = tvTwo.text
        changePopValue(null, null, 1, null)
        refreshData()
        popupWindowPrice.dismiss()
      }
      tvThree.setOnClickListener {
        obPrice.set(2)
        mBinding.spinnerPriceCourse.text = tvThree.text
        changePopValue(null, null, 0, null)
        refreshData()
        popupWindowPrice.dismiss()
      }
    }
    //endregion

    //region 默认排序弹窗
    val popBindingSort =
      PopCourseSortBinding.inflate(LayoutInflater.from(context), null, false)

    popupWindowSort = PopupWindow(
      popBindingSort.root,
      ViewGroup.LayoutParams.MATCH_PARENT,
      ViewGroup.LayoutParams.WRAP_CONTENT
    )

    //一个有初始值的observable，用来显示弹窗文字是否被点击和右边的勾显示与否，被点击set值，控件获取到对应的值后改变文字颜色
    val obSort = ObservableInt(0)

    popBindingSort.apply {
      obS = obSort
      tvAll.setOnClickListener {
        obSort.set(0)
        mBinding.spinnerSortCourse.text = tvAll.text
        changePopValue(null, null, null, -1)
        refreshData()
        popupWindowSort.dismiss() // 解除popup
      }
      tvTwo.setOnClickListener {
        obSort.set(1)
        mBinding.spinnerSortCourse.text = tvTwo.text
        changePopValue(null, null, null, 0)
        refreshData()
        popupWindowSort.dismiss() // 解除popup
      }
      tvThree.setOnClickListener {
        obSort.set(2)
        mBinding.spinnerSortCourse.text = tvThree.text
        changePopValue(null, null, null, 1)
        refreshData()
        popupWindowSort.dismiss() // 解除popup
      }
    }
    //endregion

    // 点击外部消失 和 穿透事件处理
    outSideTouch(popupWindowType, popupWindowLevel, popupWindowPrice, popupWindowSort)
    setPopupCloseLiveData()
  }

  /**
   * 点击外部消失 和 穿透事件处理
   * @param popupWindow PopupWindow
   */
  private fun outSideTouch(vararg popupWindow: PopupWindow) {
    popupWindow.forEach {
      // 弹窗背景（大部分被控件遮挡）
      it.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
      it.isOutsideTouchable = true // 点击外部消失
      it.isFocusable = true  // focusable容易忽略 防止点击事件穿透  影响下方的 rv 被点击
    }
  }

  /**
   * 有一个点击事件的 穿透冲突
   * @param name String
   * @param v View
   */
  fun openPopup(name: String, v: View) {
    when (name) {
      "type" -> {
        popupWindowType.showAsDropDown(v)
        typePopupOb.value = false
      }
      "level" -> {
        popupWindowLevel.showAsDropDown(v)
        levelPopupOb.value = false
      }
      "price" -> {
        popupWindowPrice.showAsDropDown(v)
        pricePopupOb.value = false
      }
      "sort" -> {
        popupWindowSort.showAsDropDown(v)
        sortPopupOb.value = false
      }
    }
  }

  /**
   * PopupWindow 点击外部消失，其他控件部分可以点击 部分不可以点击 怎么解决
   * it.isFocusable = false 穿透  所有 都可以点击
   * rvItem 点击时  获取 popupWindow.isShowing 打开时 直接退出
   * @return false
   */

  // liveData 控制 text end 图标翻转
  val typePopupOb = SingleLiveData<Boolean>()
  private val levelPopupOb = SingleLiveData<Boolean>()
  private val pricePopupOb = SingleLiveData<Boolean>()
  private val sortPopupOb = SingleLiveData<Boolean>()

  /**
   * 关闭 popup 时 修改 liveData 翻转 图标
   */
  private fun setPopupCloseLiveData() {
    // textView点击事件触发  true
    // 关闭时的回调函数
    popupWindowType.setOnDismissListener {
      typePopupOb.value = true
    }
    popupWindowLevel.setOnDismissListener {
      levelPopupOb.value = true
    }
    popupWindowPrice.setOnDismissListener {
      pricePopupOb.value = true
    }
    popupWindowSort.setOnDismissListener {
      sortPopupOb.value = true
    }
  }
}

